package com.android.htdvideoview;

import android.app.Activity;
import android.content.Context;
import android.content.pm.ActivityInfo;
import android.util.AttributeSet;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.animation.DecelerateInterpolator;
import android.widget.ImageButton;
import android.widget.ImageView;
import android.widget.ProgressBar;
import android.widget.TextView;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.constraintlayout.widget.ConstraintLayout;

import com.sansecy.android.simplevideo.Player;

import java.util.Formatter;
import java.util.Locale;

public class VideoControllerView extends ConstraintLayout implements Cloneable, VideoControllerInterface {

    public static int PLAY_TYPE = 0;
    /**
     * 这里的缓冲指的是视频卡住了
     */
    public static final int TYPE_BUFFERING = 1;
    /**
     * 正在播放
     */
    public static final int TYPE_PLAYING = 2;
    /**
     * 播放完成
     */
    public static final int TYPE_COMPLETION = 2;
    /**
     * 播放出错
     */
    public static final int TYPE_ERROR = 2;

    public static int VIEW_MODE = 1000;
    /**
     * 正常播放模式
     */
    public static final int VIEW_MODE_NORMAL = 1001;
    /**
     * 全屏模式
     */
    public static final int VIEW_MODE_FULLSCREEN = 1002;

    private Player mPlayer;

    private TextView mEndTime;
    private TextView mCurrentTime;

    private boolean mShowing;
    private boolean mDragging;
    private static final int sDefaultTimeout = 3000;
    private boolean mFromXml;
    private boolean mListenersSet;
    private View.OnClickListener mNextListener, mPrevListener;
    StringBuilder mFormatBuilder;
    Formatter mFormatter;

    private ImageButton mPauseButton;
    private CharSequence mPlayDescription;
    private CharSequence mPauseDescription;
    ImageView mBackButton;
    TextView mTitle;
    ImageView mLoveButton;
    ProgressBar mProgress;
    private View mFooter;
    private View mHeader;
    private ViewGroup mVideoView;
    private ProgressBar mProgressBar;

    public VideoControllerView(@NonNull Context context) {
        this(context, null);
    }

    public VideoControllerView(@NonNull Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
        init();
    }

    private void init() {
        LayoutInflater.from(getContext()).inflate(R.layout.video_controller, this, true);
        mHeader = findViewById(R.id.header);
        mFooter = findViewById(R.id.footer);
        mCurrentTime = findViewById(R.id.tv_progress);
        mEndTime = findViewById(R.id.tv_total_time);
        mBackButton = findViewById(R.id.iv_back);
        mTitle = findViewById(R.id.tv_title);
        mLoveButton = findViewById(R.id.iv_love);
        mProgress = findViewById(R.id.seekBar);
        mProgress.setMax(1000);
        mProgressBar = findViewById(R.id.progressBar);
        mFormatBuilder = new StringBuilder();
        mFormatter = new Formatter(mFormatBuilder, Locale.getDefault());
        View zoomButton = findViewById(R.id.iv_zoom);
        zoomButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if (isFullscreen) {
                    exitFullScreen();
                } else {
                    enterFullScreen();
                }
            }
        });
    }

    public void attachToVideoView(final Player videoView) {
        if (videoView == null) {
            return;
        }
        mPlayer = videoView;
        mVideoView = (ViewGroup) videoView;
        mVideoView.addView(this);
//        float x = mVideoView.getX();
//        float y = mVideoView.getY();
//        VideoControllerView.this.setX(x);
//        VideoControllerView.this.setY(y);
//        ViewGroup.LayoutParams layoutParams = getLayoutParams();
//        layoutParams.width = mVideoView.getWidth();
//        layoutParams.height = mVideoView.getHeight();
//        setLayoutParams(layoutParams);
//        if (mHeader != null) {
//            mHeader.setY(-mHeader.getHeight());
//        }
//        if (mFooter != null) {
//            mFooter.setY(mVideoView.getHeight() + mFooter.getHeight());
//        }
        mVideoView.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View v) {
                if (mShowing) {
                    hide();
                } else {
                    show();
                }
            }
        });
        setMediaPlayer(videoView);
        post(mLoadingProgress);
        mVideoView.requestFocus();
        mProgress.setFocusable(false);
        mProgress.clearFocus();
        show();
    }

    private void reset() {
        mProgress.setVisibility(GONE);
        mProgressBar.setVisibility(GONE);
    }

    private boolean isFullscreen = false;

    public void setMediaPlayer(Player player) {
        mPlayer = player;
        updatePausePlay();
    }

    private final Runnable mLoadingProgress = new Runnable() {
        @Override
        public void run() {
            if (mPlayer.getCurrentPosition() == 0) {
                mProgressBar.setVisibility(VISIBLE);
                post(mLoadingProgress);
            } else {
                mProgressBar.setVisibility(GONE);
                removeCallbacks(mLoadingProgress);
            }
        }
    };

    public void updatePausePlay() {
        if (mPauseButton == null)
            return;
        if (mPlayer.isPlaying()) {
            mPauseButton.setImageResource(R.drawable.ic_pause);
            mPauseButton.setContentDescription(mPauseDescription);
        } else {
            mPauseButton.setImageResource(R.drawable.ic_play);
            mPauseButton.setContentDescription(mPlayDescription);
        }
    }

    private final Runnable mShowProgress = new Runnable() {
        @Override
        public void run() {
            int pos = setProgress();
            if (mShowing && mPlayer.isPlaying()) {
                postDelayed(mShowProgress, 1000 - (pos % 1000));
            }
        }
    };

    @Override
    protected void onDetachedFromWindow() {
        super.onDetachedFromWindow();
        reset();
        removeCallbacks(mShowProgress);
        removeCallbacks(mLoadingProgress);
    }

    public abstract class OnDoubleClickListener implements View.OnClickListener {
        private static final long DOUBLE_TIME = 1000;
        private long lastClickTime = 0;

        @Override
        public void onClick(View v) {
            Log.d(TAG, "onClick: ");
            long currentTimeMillis = System.currentTimeMillis();
            if (currentTimeMillis - lastClickTime < DOUBLE_TIME) {
                onDoubleClick(v);
            }
            lastClickTime = currentTimeMillis;
        }

        public abstract void onDoubleClick(View v);
    }

//    @Override
//    public boolean dispatchTouchEvent(MotionEvent ev) {
//        boolean intercept = false;
//
//        int action = ev.getAction();
//        switch (action) {
//            case MotionEvent.ACTION_DOWN:
//                removeDelayDismiss();
//                if (mShowing) {
//                    hide();
//                } else {
//                    show();
//                }
//                intercept = true;
//                break;
//            case MotionEvent.ACTION_UP:
//                delayDismiss();
//                intercept = false;
//                break;
//            case MotionEvent.ACTION_CANCEL:
//                hide();
//                intercept = false;
//                break;
//        }
//        return intercept;
//    }

    public void setTitle(String title) {
        mTitle.setText(String.valueOf(title));
    }

    private Runnable delayDismissRunnable = new Runnable() {
        @Override
        public void run() {
//            hide();
        }
    };

    public void delayDismiss() {
        postDelayed(delayDismissRunnable, 3000);
    }

    public void removeDelayDismiss() {
        removeCallbacks(delayDismissRunnable);
    }

    private boolean mInAnimation = false;
    private static final String TAG = "VideoController-App";
    private boolean mUseAnimation = false;

    public void show() {
        if (!mShowing) {
            setProgress();
//            if (mUseAnimation) {
//                if (mInAnimation) {
//                    return;
//                }
//                final float headerHeight = mHeader.getHeight();
//                final float footerHeight = mFooter.getHeight();
//                final float headerY = mHeader.getY();
//                ValueAnimator animator = ValueAnimator.ofFloat(0, 1);
//                animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
//                    @Override
//                    public void onAnimationUpdate(ValueAnimator animation) {
//                        float value = (float) animation.getAnimatedValue();
//                        mHeader.setY(headerY + headerHeight * value);
//                        Log.d(TAG, "onAnimationUpdate:  mHeader.getY() = " + mHeader.getY());
//                        mFooter.setY(mVideoView.getBottom() - footerHeight * value);
//                        Log.d(TAG, "onAnimationUpdate:  mFooter.getY() = " + mFooter.getY());
//
//                    }
//                });
//                animator.addListener(new AnimatorListenerAdapter() {
//                    @Override
//                    public void onAnimationStart(Animator animation) {
//                        mInAnimation = true;
//                        mShowing = true;
//                    }
//
//                    @Override
//                    public void onAnimationEnd(Animator animation) {
//                        mInAnimation = false;
//                    }
//                });
//                animator.setDuration(500);
//                animator.setInterpolator(PROGRESS_ANIM_INTERPOLATOR);
//                animator.start();
//            } else {
//
//            }
//            mHeader.setY(0);
//            int y = mVideoView.getBottom() - mFooter.getHeight();
//            mFooter.setY(y);
            mHeader.setVisibility(VISIBLE);
            mFooter.setVisibility(VISIBLE);
            mShowing = true;
        }
        updatePausePlay();
        post(mShowProgress);
    }

    public void hide() {
        if (mShowing) {
//            if (mUseAnimation) {
//                if (mInAnimation) {
//                    return;
//                }
//                removeCallbacks(mShowProgress);
//                final float headerHeight = mHeader.getHeight();
//                final float footerHeight = mFooter.getHeight();
//                ValueAnimator animator = ValueAnimator.ofFloat(0, 1);
//                animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
//                    @Override
//                    public void onAnimationUpdate(ValueAnimator animation) {
//                        float value = (float) animation.getAnimatedValue();
//                        mHeader.setY(-headerHeight * value);
//                        mFooter.setY(mVideoView.getBottom() - footerHeight + footerHeight * value);
//                        Log.d(this.getClass().getName(), "onAnimationUpdate: " + mFooter.getY());
//                    }
//                });
//                animator.addListener(new AnimatorListenerAdapter() {
//                    @Override
//                    public void onAnimationStart(Animator animation) {
//                        mInAnimation = true;
//                    }
//
//                    @Override
//                    public void onAnimationEnd(Animator animation) {
//                        mShowing = false;
//                        mInAnimation = false;
//                    }
//                });
//                animator.setDuration(500);
//                animator.setInterpolator(PROGRESS_ANIM_INTERPOLATOR);
//                animator.start();
//            } else {
//
//            }
//            mHeader.setY(-mHeader.getHeight());
//            mFooter.setY(mVideoView.getHeight());
            mHeader.setVisibility(GONE);
            mFooter.setVisibility(GONE);
            mShowing = false;
        }
    }

    ViewGroup parent;

    public void enterFullScreen() {
        parent = (ViewGroup) mVideoView.getParent();
        parent.removeView(mVideoView);
//            final VideoControllerView controller = (VideoControllerView) clone();
        final ViewGroup contentView = (ViewGroup) Utils.findDecorView(VideoControllerView.this);
        if (contentView != null) {
            Activity activity = (Activity) mVideoView.getContext();
            activity.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
            ViewGroup decorView = (ViewGroup) activity.getWindow().getDecorView();
            decorView.addView(mVideoView);
            Utils.hideStatusBar(activity);
        }
        VIEW_MODE = VIEW_MODE_FULLSCREEN;
        isFullscreen = true;
    }

    public void exitFullScreen() {
        ViewGroup contentView = (ViewGroup) Utils.findDecorView(this);
        if (contentView != null) {
            Activity activity = (Activity) mVideoView.getContext();
            activity.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
            contentView.removeView(mVideoView);
            Utils.showStatusBar(activity);
        }
        if (parent != null) {
            parent.addView(mVideoView);
        }
        isFullscreen = false;
        VIEW_MODE = VIEW_MODE_NORMAL;
    }

    private static final DecelerateInterpolator PROGRESS_ANIM_INTERPOLATOR = new DecelerateInterpolator();

    public int setProgress() {
        if (mPlayer == null || mDragging) {
            return 0;
        }
        int position = mPlayer.getCurrentPosition();
        int duration = mPlayer.getDuration();
        if (mProgress != null) {
            if (duration > 0) {
                // use long to avoid overflow
                long pos = 1000L * position / duration;
                mProgress.setProgress((int) pos);
            }
            int percent = mPlayer.getBufferPercentage();
            mProgress.setSecondaryProgress(percent * 10);
        }
        Log.d(this.getClass().getName(), "setProgress: " + position);
        if (mEndTime != null)
            mEndTime.setText(stringForTime(duration));
        if (mCurrentTime != null)
            mCurrentTime.setText(stringForTime(position));

        return position;
    }

    private String stringForTime(int timeMs) {
        int totalSeconds = timeMs / 1000;

        int seconds = totalSeconds % 60;
        int minutes = (totalSeconds / 60) % 60;
        int hours = totalSeconds / 3600;

        mFormatBuilder.setLength(0);
        if (hours > 0) {
            return mFormatter.format("%d:%02d:%02d", hours, minutes, seconds).toString();
        } else {
            return mFormatter.format("%02d:%02d", minutes, seconds).toString();
        }
    }
}
